﻿<h3 class="important-tittle">Types and Configuration</h3>

<p>
    LiveCharts can plot any type, even user-defined types, without losing the beauty of a strongly typed language,
    the concept is simple, you pass collection of generic values, then LiveCharts needs a function to pull X and Y (if it is a Cartesian chart),
    you don't really need to define each type to plot it,
    the library already knows how to plot, <i class="text-muted">double, int, decimal, short, float, long</i> and also
    some other specially designed classes, <a href="https://github.com/beto-rodriguez/Live-Charts/blob/master/Core/Defaults/ObservableValue.cs">ObservableValue</a>,
    <a href="https://github.com/beto-rodriguez/Live-Charts/blob/master/Core/Defaults/ObservablePoint.cs">ObservablePoint</a>,
    <a href="https://github.com/beto-rodriguez/Live-Charts/blob/master/Core/Defaults/ScatterPoint.cs">ScatterPoint</a>,
    <a href="https://github.com/beto-rodriguez/Live-Charts/blob/master/Core/Defaults/DateTimePoint.cs">DateTimePoint</a>,
    <a href="https://github.com/beto-rodriguez/Live-Charts/blob/master/Core/Defaults/HeatPoint.cs">HeatPoint</a>,
    <a href="https://github.com/beto-rodriguez/Live-Charts/blob/master/Core/Defaults/OHCLPoint.cs">OHLCPoint</a>,
    <a href="https://github.com/beto-rodriguez/Live-Charts/blob/master/Core/Defaults/PolarPoint.cs">PolarPoint</a>,
    all these classes notify the chart to update when a property changes, examples in this web site uses these objects,
    you can always define your own type.
</p>

<pre class="prettyprint">var doubleValues = new ChartValues&lt;double> { 1, 2 ,3 };
var intValues = new ChartValues&lt;int> { 1, 2 ,3 };

//the observable value class is really helpful, it notifies the chart to update
//every time the ObservableValue.Value property changes
var observableValues = new ChartValues&lt;LiveCharts.Defaults.ObservableValue> 
{ 
    new LiveCharts.Defaults.ObservableValue(1), //initializes Value property as 1
    new LiveCharts.Defaults.ObservableValue(2),
    new LiveCharts.Defaults.ObservableValue(3)
};</pre>

<p>
    Notice the chart <b>always</b> uses X and Y coordinates (if Cartesian chart), but then
    how is it possible that the library is able to plot only <i>double</i> or <i>int</i> or <i>long</i> values?
</p>

<p>
    Simple, <i>X</i> is the index of the value in the array, and <i>Y</i> is the value you passed, this is only true
    if you used a Horizontal Series, if you used a Vertical Series then <i>X</i> is the value and <i>Y</i> the index,
    so for the next collection of values
</p>

<pre class="prettyprint">var myValues = new LiveCharts.ChartValues&lt;double&gt;
{
  10, //index 0
  6,  //index 1
  9,  //index 2
  2,  //index 3
  7   //index 4
}</pre>

<p>
    The real coordinates are actually:
</p>

<div class="table-responsive">
    <table class="table table-striped table-bordered">
        <thead>
            <tr>
                <th rowspan="2" class="text-center" style="width: 34%">Value</th>
                <th colspan="2" class="text-center" style="width: 33%">Horizontal Series</th>
                <th colspan="2" class="text-center" style="width: 33%">Vertical Series</th>
            </tr>
            <tr>
                <th class="text-center">X <small class="text-muted"><i style="font-weight: 300">(indexed)</i></small></th>
                <th class="text-center">Y</th>
                <th class="text-center">X</th>
                <th class="text-center">Y <small class="text-muted"><i style="font-weight: 300">(indexed)</i></small></th>
            </tr>
        </thead>
        <tbody>
            <tr class="text-center">
                <td>10</td>
                <td>0</td>
                <td>10</td>
                <td>10</td>
                <td>0</td>
            </tr>
            <tr class="text-center">
                <td>6</td>
                <td>1</td>
                <td>6</td>
                <td>6</td>
                <td>1</td>
            </tr>
            <tr class="text-center">
                <td>9</td>
                <td>2</td>
                <td>9</td>
                <td>9</td>
                <td>2</td>
            </tr>
            <tr class="text-center">
                <td>2</td>
                <td>3</td>
                <td>2</td>
                <td>2</td>
                <td>3</td>
            </tr>
            <tr class="text-center">
                <td>7</td>
                <td>4</td>
                <td>7</td>
                <td>7</td>
                <td>4</td>
            </tr>
        </tbody>
    </table>
</div>

<p>
    And the already defined configuration that pulls this coordinates is
</p>

<p>For <b>Horizontal Series</b></p>

<pre class="prettyprint">new CartesianMapper&lt;double&gt;()
  .X((value, index) => index) //use the index as X
  .Y((value, index) => value) //use the value as Y</pre>

<p>For <b>Vertical Series</b></p>

<pre class="prettyprint">new CartesianMapper&lt;double&gt;()
  .X((value, index) => value) //use the value as X
  .Y((value, index) => index) //use the index as Y</pre>

<p>
    X and Y is only necessary for Cartesian charts, but how about if you need to configure a polar chart (radius and angle) or a financial series,
    because my memory is really bad I created a reminder, the <i>Mappers</i> class, this class returns a new instance of the correct mapper,
    it has many options, <i>Xy, Financial, Bubble and Polar</i>, the mappers above can be replaced with:
</p>

<pre class="prettyprint">Mappers.Xy&lt;double&gt;()
  .X((value, index) => index) //use the index as X
  .Y((value, index) => value) //use the value as Y</pre>

<p>
    Here are some examples with multiple mappers, it is really intuitive according to your case.
</p>

<pre class="prettyprint">//X and Y
var mapper = Mappers.Xy&lt;ObservablePoint>() //in this case value is of type &lt;ObservablePoint>
    .X(value => value.X) //use the X property as X
    .Y(value => value.Y); //use the Y property as Y

//X, Y and Weight
var mapper = Mappers.Bubble&lt;BubblePoint>()
                .X(value => value.X)
                .Y(value => value.Y)
                .Weight(value => value.Weight);

//Angle and Radius
var mapper = Mappers.Polar&lt;PolarPoint>()
    .Radius(value => value.Radius) //use the radius property as radius for the plotting
    .Angle(value => value.Angle); //use the angle property as angle for the plotting

//Open, High, Low and Close
var mapper = Mappers.Financial&lt;OhlcPoint>()
                .X((value, index) => index)
                .Open(value => value.Open)
                .High(value => value.High)
                .Low(value => value.Low)
                .Close(value => value.Close);</pre>

<p>
    You can set mappers in several ways
</p>

<h4>1. Globally</h4>

<p>
    This method saves the configuration at your application level, every time LiveCharts detects this type in a <i>Chart Values</i> instance, 
    it will use this mapper only if the SeriesCollection mapper and Series mapper are null.
</p>

<pre class="prettyprint">var mapper1 = Mappers.Xy&lt;int&gt;()
  .X((value, index) =&gt; index) 
  .Y(value =&gt; value);
LiveCharts.Charting.For&lt;int&gt;(mapper1, SeriesOrientation.Horizontal); //when horizontal

var mapper2 = Mappers.Xy&lt;int&gt;()
  .X(value =&gt; value) //use the value (int) as X
  .Y((value, index) =&gt; index);
LiveCharts.Charting.For&lt;int&gt;(mapper2, SeriesOrientation.Vertical); //when vertical
</pre>

<p>
    Another example with a custom class, the <i>ObservablePoint</i> class that only contains 2 properties, <i>X</i> and <i>Y</i>,
    also notice this time I am using the same configuration for both, Horizontal and Vertical, without passing the second argument (Orientation).
</p>

<pre class="prettyprint">
For&lt;ObservablePoint&gt;(Mappers.Xy&lt;ObservablePoint&gt;()
  .X((value, index) =&gt; value.X) 
  .Y(value =&gt; value.Y));
</pre>

<p>
    If this is not clear enough you find a more detailed explanation at <a href="https://github.com/beto-rodriguez/Live-Charts/blob/master/Core/Charting.cs#L43">source code</a>
</p>

<h4>2. At Series Collection Level</h4>

<p>
    When you define a Series collection instance you can also pass a default configuration, this configuration overrides the global configuration
    and will be set only if Series configuration is null.
</p>

<pre class="prettyprint">var mapper = Mappers.Xy&lt;MyClass&gt;().X(v => v.XProp).Y(v => v.YProp);
var seriesCollection = new SeriesCollection(mapper);
myChart.SeriesCollection = seriesCollection;</pre>

<h4>3. At a specific series</h4>

<p>
    Finally you can also define a mapper only for a series, this will override the globally and SeriesCollection configuration
</p>

<pre class="prettyprint">var mapper = Mappers.Xy&lt;MyClass&gt;().X(v => v.XProp).Y(v => v.YProp);
var pieSeries = new PieSeries(mapper);</pre>

<h3>Notify the chart to update automatically</h3>

<p>
    You can also implement <i>IObservableChartPoint</i>, so the chart will update automatically when a property
    of a custom type changes, in the next example you will see definition of the <i>ObservableValue</i> class,
    which notifies the chart to update when the <i>Value</i> property changes, the concept is really simple,
    you only need to invoke the <i>PointChanged</i> event every time the <i>Value</i> property is set.
</p>

<pre class="prettyprint">public class ObservableValue : IObservableChartPoint
{
    private double _value;
    public ObservableValue()
    {
            
    }

    public ObservableValue(double value)
    {
        Value = value;
    }
 
   public event Action PointChanged;
   public double Value
   {
       get { return _value; }
       set
       {
           _value = value;
           OnPointChanged();
       }
   }
 
   protected void OnPointChanged()
   {
       if (PointChanged != null) PointChanged.Invoke();
   }
}</pre>

<p>
    you can find more examples <a href="https://github.com/beto-rodriguez/Live-Charts/tree/master/Core/Defaults">here</a>
</p>
